use crate::dto::{
    dept::DeptList,
    post::SysPostList,
    role::{SysRoleList, SysRoleListFlag},
};
use crate::entity::sys_user::SysUser;
use hypers::oapi::{ToParameter, ToSchema};
use rbatis::rbdc::datetime::DateTime;
use serde::{Deserialize, Serialize};

// 验证码返回
#[derive(Serialize, Deserialize, Clone, Debug, ToSchema)]
#[hypers(schema(rename_all = "camelCase"))]
pub struct CaptchaRes {
    #[serde(rename = "captchaEnabled")]
    pub captcha_enabled: Option<bool>,
    pub img: String,
    pub uuid: String,
}

// 登录请求参数
#[derive(Serialize, Deserialize, Clone, Debug, ToSchema)]
pub struct LoginReq {
    pub code: Option<String>,
    pub password: Option<String>,
    pub username: Option<String>,
    pub uuid: Option<String>,
}

// 登录返回
#[derive(Serialize, Deserialize, Clone, Debug, ToSchema)]
pub struct LoginRes {
    pub token: String,
}

// 登录返回
#[derive(Serialize, Deserialize, Clone, Debug, ToSchema)]
pub struct UserInfo {
    pub permissions: Vec<String>,
    pub roles: Vec<String>,
    pub user: SysUser,
}

#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)]
#[hypers(schema(rename_all = "camelCase"))]
#[serde(rename_all(serialize = "camelCase"))]
pub struct SysUserList {
    pub user_id: i64,
    pub dept_id: Option<i64>,
    pub user_name: String,
    pub nick_name: String,
    pub user_type: Option<String>,
    pub email: Option<String>,
    #[serde(rename(serialize = "phonenumber"))]
    #[serde(rename(deserialize = "phonenumber"))]
    pub phone_number: Option<String>,
    pub sex: Option<String>,
    pub avatar: Option<String>,
    pub password: Option<String>,
    pub status: Option<String>,
    pub del_flag: Option<String>,
    pub login_ip: Option<String>,
    pub login_date: Option<DateTime>,
    pub create_by: Option<String>,
    pub create_time: Option<DateTime>,
    pub update_by: Option<String>,
    pub update_time: Option<DateTime>,
    pub remark: Option<String>,
    pub real_name: Option<String>,
    pub expire_time: Option<i64>,
    pub dept: Option<DeptList>,
}

#[derive(Debug, Serialize, Deserialize, Clone, ToParameter)]
#[hypers(parameter(rename_all = "camelCase"))]
#[serde(rename_all(deserialize = "camelCase"))]
pub struct SysUserListPayload {
    #[serde(rename = "pageNum")]
    pub page_num: u64,
    #[serde(rename = "pageSize")]
    pub page_size: u64,
    pub user_name: Option<String>,
    #[serde(rename(deserialize = "phonenumber"))]
    pub phone_number: Option<String>,
    pub status: Option<String>,
    pub dept_id: Option<i64>,
    #[serde(rename(deserialize = "params[beginTime]"))]
    #[hypers(parameter(rename = "params[beginTime]"))]
    #[hypers(parameter(value_type = Option<String>))]
    pub begin_time: Option<DateTime>,
    #[serde(rename(deserialize = "params[endTime]"))]
    #[hypers(parameter(rename = "params[endTime]"))]
    #[hypers(parameter(value_type = Option<String>))]
    pub end_time: Option<DateTime>,
}

#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)]
#[hypers(schema(rename_all = "camelCase"))]
#[serde(rename_all(serialize = "camelCase"))]
pub struct SysUserDetail {
    pub posts: Vec<SysPostList>,
    pub roles: Vec<SysRoleList>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub post_ids: Option<Vec<i64>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub role_ids: Option<Vec<i64>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub user: Option<SysUserList>,
}

#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)]
#[hypers(schema(rename_all = "camelCase"))]
#[serde(rename_all(deserialize = "camelCase"))]
pub struct SysUserChangeStatusPayload {
    pub status: String,
    pub user_id: i64,
}

#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)]
#[hypers(schema(rename_all = "camelCase"))]
#[serde(rename_all(deserialize = "camelCase"))]
pub struct SysUserModifyPayload {
    pub dept_id: Option<i64>,
    pub email: Option<String>,
    #[serde(rename(deserialize = "phonenumber"))]
    pub phone_number: Option<String>,
    pub nick_name: String,
    pub user_name: String,
    pub password: String,
    pub post_ids: Vec<i64>,
    pub role_ids: Vec<i64>,
    pub sex: Option<String>,
    pub status: Option<String>,
    pub remark: Option<String>,
}

#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)]
#[hypers(schema(rename_all = "camelCase"))]
#[serde(rename_all(deserialize = "camelCase"))]
pub struct SysUserEditPayload {
    pub user_id: Option<i64>,
    pub dept_id: Option<i64>,
    pub email: Option<String>,
    #[serde(rename(deserialize = "phonenumber"))]
    pub phone_number: Option<String>,
    pub nick_name: String,
    pub post_ids: Vec<i64>,
    pub role_ids: Vec<i64>,
    pub sex: Option<String>,
    pub status: Option<String>,
    pub remark: Option<String>,
}

#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)]
#[hypers(schema(rename_all = "camelCase"))]
#[serde(rename_all(deserialize = "camelCase"))]
pub struct SysUserEditPwdPayload {
    pub user_id: i64,
    pub password: String,
}

#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)]
#[hypers(schema(rename_all = "camelCase"))]
#[serde(rename_all(deserialize = "camelCase"))]
pub struct SysUserAuthRole {
    pub user: Option<SysUserList>,
    pub roles: Vec<SysRoleListFlag>,
}

#[derive(Debug, Serialize, Deserialize, Clone, ToParameter)]
#[hypers(parameter(rename_all = "camelCase"))]
#[serde(rename_all(deserialize = "camelCase"))]
pub struct SysAuthPayload {
    pub user_id: i64,
    #[hypers(parameter(value_type = Option<String>))]
    pub role_ids: Option<String>,
}

#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)]
#[hypers(schema(rename_all = "camelCase"))]
#[serde(rename_all(serialize = "camelCase"))]
pub struct SysUserProfile {
    pub admin: bool,
    pub user_id: i64,
    pub dept_id: Option<i64>,
    pub user_name: String,
    pub nick_name: String,
    pub user_type: Option<String>,
    pub email: Option<String>,
    #[serde(rename(serialize = "phonenumber"))]
    pub phone_number: Option<String>,
    pub sex: Option<String>,
    pub avatar: Option<String>,
    pub password: Option<String>,
    pub status: Option<String>,
    pub del_flag: Option<String>,
    pub login_ip: Option<String>,
    pub login_date: Option<DateTime>,
    pub create_by: Option<String>,
    pub create_time: Option<DateTime>,
    pub update_by: Option<String>,
    pub update_time: Option<DateTime>,
    pub remark: Option<String>,
    pub real_name: Option<String>,
    pub expire_time: Option<i64>,
    pub dept: Option<DeptList>,
    pub roles: Option<Vec<SysRoleList>>,
    pub post_group: Option<String>,
    pub role_group: Option<String>,
}

impl SysUserList {
    pub fn into_sys_user_profile(self) -> SysUserProfile {
        SysUserProfile {
            admin: false,
            user_id: self.user_id,
            dept_id: self.dept_id,
            user_name: self.user_name,
            nick_name: self.nick_name,
            user_type: self.user_type,
            email: self.email,
            phone_number: self.phone_number,
            sex: self.sex,
            avatar: self.avatar,
            password: self.password,
            status: self.status,
            del_flag: self.del_flag,
            login_ip: self.login_ip,
            login_date: self.login_date,
            create_by: self.create_by,
            create_time: self.create_time,
            update_by: self.update_by,
            update_time: self.update_time,
            remark: self.remark,
            real_name: self.real_name,
            expire_time: self.expire_time,
            dept: None,
            roles: None,
            post_group: None,
            role_group: None,
        }
    }
}

#[derive(Debug, Serialize, Deserialize, Clone, ToSchema, ToParameter)]
#[hypers(parameter(rename_all = "camelCase"))]
#[serde(rename_all(deserialize = "camelCase"))]
pub struct SysUpdateUserPwdPayload {
    pub old_password: Option<String>,
    pub new_password: Option<String>,
}
